﻿using System;
using System.Collections.Generic;
using System.IO;
using Citi.RoutineBase;
using Citi.Helpers;

namespace Citi.GenericApplications.SchedulerUi
{
    public class Refresh : IExecutableRoutine
    {
        string TempPath = @"C:\Temp\{0}";

        public IEnumerable<RoutineParameter> Parameters
        {
            get
            {
                return new List<RoutineParameter> { 
                    new RoutineParameter{ Description = "Excel path to refresh", Name ="ExcelFile", Nullable = false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Pwd file. Only filename. E.g. ExcelPassword.pwd", Name ="PwdFile", Nullable = true, Required = false, Type = typeof(string)},
                    new RoutineParameter{ Description = "Do you want to remove data links and connections?", Name ="RemoveDataLink", Nullable = false, Required = true, Type = typeof(bool)},
                    new RoutineParameter{ Description = "Do you want to transform Table To Range?", Name ="TransformTableToRange", Nullable = true, Required = false, Type = typeof(bool)},
                    new RoutineParameter{ Description = "Run on background? Note: running in background can affect the execution if it continues and the refresh is not completely refresh. Default: false", 
                        Name ="RunOnBackground", Nullable = true, Required = false, Type = typeof(bool)},
                    new RoutineParameter{ Description = "Path to save. If not provided the file will be replaced", Name ="PathToSaveRefreshedFile", Nullable = true, Required = false, Type = typeof(string)},
                    new RoutineParameter{ Description = "If you want to start a routine when it's finished, insert the Routine Id.", 
                        Name ="SuccessorRoutineId", Nullable = true, Required = false, Type = typeof(int)}
                };
            }
        }

        public void Rollback(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            Util.KillExcelProcesses();
        }

        public void Start(DateTime scheduledDate, ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            var excelFile = parameters["ExcelFile"].ToString();
            var pwdFile = parameters.ContainsKey("PwdFile") ? parameters["PwdFile"].ToString() : null;
            var removeDataLink = bool.Parse(parameters["RemoveDataLink"].ToString());
            var pathToSaveRefreshedFile = parameters.ContainsKey("PathToSaveRefreshedFile") ? parameters["PathToSaveRefreshedFile"].ToString() : null;
            var transformTableToRange = parameters.ContainsKey("TransformTableToRange") ? bool.Parse(parameters["TransformTableToRange"].ToString()) : false;
            var runOnBackground = parameters.ContainsKey("RunOnBackground") ? bool.Parse(parameters["RunOnBackground"].ToString()) : false;
            var successorRoutineId = parameters.ContainsKey("SuccessorRoutineId") ? parameters["SuccessorRoutineId"].ToString() : null;

            if (string.IsNullOrWhiteSpace(pathToSaveRefreshedFile))
                pathToSaveRefreshedFile = excelFile;

            var excelTemp = RefreshAll(excelFile, pathToSaveRefreshedFile, pwdFile, removeDataLink, currentAction, transformTableToRange, runOnBackground);

            if (removeDataLink)
                excelTemp = RefreshAll(excelFile, pathToSaveRefreshedFile, pwdFile, false, currentAction, transformTableToRange, runOnBackground);

            currentAction.Description = "Copying file to final folder";
            File.Copy(excelTemp, pathToSaveRefreshedFile, true);
            File.Delete(excelTemp);

            currentAction.Description = string.Format("File copied to {0}", pathToSaveRefreshedFile);

            Util.ScheduleSuccessorRoutine(successorRoutineId, currentAction);
            Util.KillExcelProcesses();
        }

        private string RefreshAll(string excelFile, string pathToSaveRefreshedFile, string pwdFile, bool removeDataLink, ICurrentAction currentAction, bool transformTableToRange, bool runOnBackground)
        {
            if (!File.Exists(excelFile))
                throw new FileNotFoundException(string.Format("{0} does not exist.", excelFile));

            var excelTemp = string.Format(TempPath, Path.GetFileName(pathToSaveRefreshedFile));

            try
            {
                currentAction.Description = string.Format("Copying file local from {0} to {1}", excelFile, excelTemp);
                File.Copy(excelFile, excelTemp, true);
                currentAction.Description = "File copied";

                currentAction.Description = string.Format("Refreshing file {0}", excelTemp);

                ExcelHelper.RunOnBackground = runOnBackground;
                ExcelHelper.RefreshAll(excelTemp, pwdFile, false, false);
                currentAction.Description = "Excel file was successfully refreshed";

                if (removeDataLink)
                {
                    currentAction.Description = "Removing data connections";
                    ExcelHelper.RemoveDataLinks(excelTemp, null, pwdFile);
                    currentAction.Description = "Data Connections removed";
                }

                if (transformTableToRange)
                {
                    currentAction.Description = "Transforming table to range";
                    ExcelHelper.TransformTableToRange(excelTemp, null, pwdFile);
                    currentAction.Description = "Tables converted to ranges";
                }

                return excelTemp;
            }
            catch (Exception e)
            {
                if (File.Exists(excelTemp))
                    File.Delete(excelTemp);

                throw e;
            }
        }

        public void Stop(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {

        }
    }
}
